using System;
using System.Collections.Generic;
using System.Drawing;
using MEA.AE_Data.Config;

namespace MEA.Chart
{
	public class CaCrDisplay
	{
		private struct StartEndCaCrDisp
		{
			public int startCaCr;

			public int endCaCr;

			public StartEndCaCrDisp(int a, int b)
			{
				startCaCr = a;
				endCaCr = b;
			}
		}

		public struct StartEndCaCrDispf
		{
			public float startCaCr;

			public float endCaCr;

			public StartEndCaCrDispf(float a, float b)
			{
				startCaCr = a;
				endCaCr = b;
			}
		}

		private enum ECaCrDeb
		{
			eNoStartDeb,
			eStartDeb,
			eDebRun,
			eEndDeb
		}

		private enum ECaCrShowData
		{
			eNotOkTest,
			eTestOk,
			eTestDebWasOk
		}

		public enum EDrawLineStat
		{
			eStartDrow,
			eDrawTmpGreyLine,
			eGreyLineDrow,
			eDrawTestOk,
			eDrawEnd
		}

		private const int penWidth = 6;

		private const int minRpm = 400;

		private const int maxRpm = 1000;

		private const int testPositivSec = 2;

		private const float testForNegativTime = 0.2f;

		private const int absMaxCaCrDiffVal = 10;

		public List<StartEndCaCrDispf> PosOfCaCrDispf;

		public List<EDrawLineStat> PosOfCaCrDispfLiveView;

		public int fnChkTestPos;

		private float deltaT;

		private Pen pen;

		private Pen pen0;

		private float locYpos;

		private ConfigData.e_ECUID ecu;

		private int maxXLen;

		private ConfigData.EGraphicAspect aspect;

		private int pointCountForPosTestSec;

		private int pointCountForDeboncing;

		private int debCnt;

		private int posTestCnt;

		private PointF pointSave;

		private PointF pointDraw;

		private EDrawLineStat stat;

		private bool lastCaCrVal;

		private Graphics g;

		private Koordsyst koo;

		private bool visible;

		public CaCrDisplay()
		{
			PosOfCaCrDispf = new List<StartEndCaCrDispf>();
			deltaT = 0f;
			fnChkTestPos = 0;
		}

		public CaCrDisplay(int posCaCrDiff, int posPropSpeed, float difTime, ConfigData.e_ECUID ecu)
		{
			deltaT = difTime / 1000f;
			fnChkTestPos = 0;
			this.ecu = ecu;
			fnChkTestPos = posCaCrDiff;
			if (ecu == ConfigData.e_ECUID.A)
			{
				locYpos = 0.2f;
				pen = new Pen(Color.FromArgb(160, 172, 237, 50), 6f);
			}
			else
			{
				locYpos = -0.2f;
				pen = new Pen(Color.FromArgb(160, 12, 162, 250), 6f);
			}
			pen0 = new Pen(Color.FromArgb(160, 176, 192, 192), 6f);
			PosOfCaCrDispfLiveView = new List<EDrawLineStat>();
			aspect = ConfigData.EGraphicAspect.eShowGraphShowLiveView;
			pointCountForPosTestSec = (int)(2f / deltaT);
			pointCountForDeboncing = (int)(0.2f / deltaT);
		}

		public CaCrDisplay(ref List<PointF> fnList, ref List<PointF> rpmList, int pos, ConfigData.e_ECUID ecu)
		{
			List<PointF> list = new List<PointF>();
			List<PointF> list2 = new List<PointF>();
			List<StartEndCaCrDisp> list3 = new List<StartEndCaCrDisp>();
			new List<StartEndCaCrDisp>();
			aspect = ConfigData.EGraphicAspect.eShowGraphShowLiveViewRec;
			PosOfCaCrDispf = new List<StartEndCaCrDispf>();
			this.ecu = ecu;
			fnChkTestPos = pos;
			deltaT = Math.Abs(fnList[1].X - fnList[0].X);
			float num = 1f / deltaT;
			pointCountForPosTestSec = (int)(2f * num);
			pointCountForDeboncing = (int)(0.2f * num);
			debCnt = 0;
			posTestCnt = 0;
			StartEndCaCrDisp item = default(StartEndCaCrDisp);
			if (ecu == ConfigData.e_ECUID.A)
			{
				locYpos = 0.2f;
				pen = new Pen(Color.FromArgb(160, 172, 237, 50), 6f);
			}
			else
			{
				locYpos = -0.2f;
				pen = new Pen(Color.FromArgb(160, 12, 162, 250), 6f);
			}
			pen0 = new Pen(Color.FromArgb(160, 176, 192, 192), 6f);
			int i;
			for (i = 0; i < rpmList.Count; i++)
			{
				float y = rpmList[i].Y;
				PointF item2 = fnList[i];
				if (y > 400f && y < 1000f)
				{
					if (list.Count == 0)
					{
						item = new StartEndCaCrDisp
						{
							startCaCr = i
						};
					}
					list.Add(item2);
					if (list2.Count > 0)
					{
						list2.Clear();
					}
					continue;
				}
				list2.Add(item2);
				if (list.Count > 0 && list2.Count > 1)
				{
					if (list.Count > pointCountForPosTestSec)
					{
						item.endCaCr = i;
						list3.Add(item);
					}
					list.Clear();
				}
			}
			maxXLen = (int)((float)i * deltaT);
			if ((float)list.Count >= 2f * num && item.endCaCr == 0)
			{
				item.endCaCr = item.startCaCr + list.Count - 1;
				list3.Add(item);
			}
			int num2 = 0;
			ECaCrDeb eCaCrDeb = ECaCrDeb.eNoStartDeb;
			StartEndCaCrDispf item3 = default(StartEndCaCrDispf);
			for (i = 0; i < list3.Count; i++)
			{
				item = list3[i];
				for (int j = item.startCaCr; j <= item.endCaCr; j++)
				{
					float y = fnList[j].Y;
					if (y <= 10f && y >= -10f)
					{
						switch (eCaCrDeb)
						{
						case ECaCrDeb.eNoStartDeb:
							eCaCrDeb = ECaCrDeb.eStartDeb;
							item3 = new StartEndCaCrDispf
							{
								startCaCr = fnList[j].X
							};
							break;
						case ECaCrDeb.eStartDeb:
							if (j - item.startCaCr > pointCountForPosTestSec)
							{
								eCaCrDeb = ECaCrDeb.eDebRun;
							}
							break;
						case ECaCrDeb.eDebRun:
							if (j == item.endCaCr)
							{
								item3.endCaCr = fnList[j].X;
								PosOfCaCrDispf.Add(item3);
								eCaCrDeb = ECaCrDeb.eNoStartDeb;
							}
							break;
						}
						num2 ^= num2;
						continue;
					}
					switch (eCaCrDeb)
					{
					case ECaCrDeb.eNoStartDeb:
					case ECaCrDeb.eStartDeb:
						if (num2++ > pointCountForDeboncing)
						{
							eCaCrDeb = ECaCrDeb.eNoStartDeb;
						}
						break;
					case ECaCrDeb.eDebRun:
						if (j == item.endCaCr)
						{
							item3.endCaCr = fnList[j].X;
							PosOfCaCrDispf.Add(item3);
							eCaCrDeb = ECaCrDeb.eNoStartDeb;
						}
						else if (num2++ > pointCountForDeboncing)
						{
							item3.endCaCr = fnList[j - 3].X;
							eCaCrDeb = ECaCrDeb.eNoStartDeb;
							PosOfCaCrDispf.Add(item3);
						}
						break;
					}
				}
			}
		}

		public void Draw(ref Graphics g, ref Koordsyst koo)
		{
			this.g = g;
			this.koo = koo;
			if (aspect == ConfigData.EGraphicAspect.eShowGraphShowLiveViewRec)
			{
				int count = PosOfCaCrDispf.Count;
				float xMin = koo.XMin;
				float xMax = koo.XMax;
				PointF pointF = koo.transformToBild(xMin, locYpos);
				PointF pointF2 = pointF;
				if (count == 0)
				{
					pointF2 = koo.transformToBild(xMax, locYpos);
					g.DrawLine(pen0, pointF, pointF2);
					return;
				}
				EDrawLineStat eDrawLineStat = EDrawLineStat.eStartDrow;
				for (int i = 0; i < count; i++)
				{
					if (eDrawLineStat == EDrawLineStat.eDrawEnd)
					{
						break;
					}
					StartEndCaCrDispf startEndCaCrDispf = PosOfCaCrDispf[i];
					if (!(startEndCaCrDispf.endCaCr >= xMin))
					{
						continue;
					}
					switch (eDrawLineStat)
					{
					case EDrawLineStat.eStartDrow:
						if (startEndCaCrDispf.startCaCr > xMin)
						{
							pointF2 = koo.transformToBild(startEndCaCrDispf.startCaCr, locYpos);
							g.DrawLine(pen0, pointF, pointF2);
							pointF = pointF2;
							if (startEndCaCrDispf.endCaCr >= xMax)
							{
								pointF2 = koo.transformToBild(xMax, locYpos);
								g.DrawLine(pen, pointF, pointF2);
								eDrawLineStat = EDrawLineStat.eDrawEnd;
							}
							else
							{
								pointF2 = koo.transformToBild(startEndCaCrDispf.endCaCr, locYpos);
								g.DrawLine(pen, pointF, pointF2);
								eDrawLineStat = EDrawLineStat.eGreyLineDrow;
							}
						}
						else if (startEndCaCrDispf.endCaCr >= xMax)
						{
							pointF2 = koo.transformToBild(xMax, locYpos);
							g.DrawLine(pen, pointF, pointF2);
							eDrawLineStat = EDrawLineStat.eDrawEnd;
						}
						else
						{
							pointF2 = koo.transformToBild(startEndCaCrDispf.endCaCr, locYpos);
							g.DrawLine(pen, pointF, pointF2);
							eDrawLineStat = EDrawLineStat.eGreyLineDrow;
						}
						break;
					case EDrawLineStat.eGreyLineDrow:
						if (startEndCaCrDispf.startCaCr >= xMax)
						{
							pointF = pointF2;
							pointF2 = koo.transformToBild(xMax, locYpos);
							g.DrawLine(pen0, pointF, pointF2);
							eDrawLineStat = EDrawLineStat.eDrawEnd;
							break;
						}
						pointF = pointF2;
						pointF2 = koo.transformToBild(startEndCaCrDispf.startCaCr, locYpos);
						g.DrawLine(pen0, pointF, pointF2);
						if (startEndCaCrDispf.endCaCr >= xMax)
						{
							pointF = pointF2;
							pointF2 = koo.transformToBild(xMax, locYpos);
							g.DrawLine(pen, pointF, pointF2);
							eDrawLineStat = EDrawLineStat.eDrawEnd;
						}
						else
						{
							pointF2 = pointF;
							pointF2 = koo.transformToBild(startEndCaCrDispf.endCaCr, locYpos);
							g.DrawLine(pen, pointF, pointF2);
							eDrawLineStat = EDrawLineStat.eGreyLineDrow;
						}
						break;
					}
				}
				if (eDrawLineStat != EDrawLineStat.eDrawEnd)
				{
					pointF = pointF2;
					pointF2 = koo.transformToBild(maxXLen, locYpos);
					g.DrawLine(pen0, pointF, pointF2);
				}
			}
			else if (aspect == ConfigData.EGraphicAspect.eShowGraphShowLiveView && visible)
			{
				redrowCaCr();
			}
		}

		private void redrowCaCr()
		{
			float num = koo.XMin / deltaT;
			float num3 = koo.XMax / deltaT;
			PointF pointF = koo.transformToBild(koo.XMin, locYpos);
			PointF pt = pointF;
			float num2 = koo.XMin;
			float x = pointSave.X;
			for (int i = (int)num; i < PosOfCaCrDispfLiveView.Count; i++)
			{
				if (num2 <= x)
				{
					pointF = koo.transformToBild(num2, locYpos);
					if (PosOfCaCrDispfLiveView[i] == EDrawLineStat.eDrawTestOk)
					{
						g.DrawLine(pen, pointF, pt);
					}
					else
					{
						g.DrawLine(pen0, pointF, pt);
					}
					pt = pointF;
					num2 += deltaT;
				}
			}
		}

		public void addToPosOfCaCrDispfLiveView(PointF pF)
		{
			int count = PosOfCaCrDispfLiveView.Count;
			if (count > 0)
			{
				stat = PosOfCaCrDispfLiveView[count - 1];
			}
			else
			{
				stat = EDrawLineStat.eStartDrow;
			}
			bool flag = ((pF.Y > 400f && pF.Y < 1000f) ? true : false);
			switch (stat)
			{
			case EDrawLineStat.eStartDrow:
				if (flag)
				{
					stat = EDrawLineStat.eDrawTmpGreyLine;
				}
				else
				{
					stat = EDrawLineStat.eGreyLineDrow;
				}
				break;
			case EDrawLineStat.eDrawTmpGreyLine:
				if (flag)
				{
					if (lastCaCrVal)
					{
						if (posTestCnt == pointCountForPosTestSec)
						{
							for (int i = count - pointCountForPosTestSec; i < count; i++)
							{
								PosOfCaCrDispfLiveView[i] = EDrawLineStat.eDrawTestOk;
							}
							stat = EDrawLineStat.eDrawTestOk;
							posTestCnt = 0;
						}
						else
						{
							posTestCnt++;
						}
					}
					else
					{
						stat = EDrawLineStat.eGreyLineDrow;
					}
				}
				else
				{
					stat = EDrawLineStat.eGreyLineDrow;
				}
				break;
			case EDrawLineStat.eDrawTestOk:
				if (flag)
				{
					if (lastCaCrVal)
					{
						debCnt ^= debCnt;
					}
					else if (debCnt > pointCountForDeboncing)
					{
						stat = EDrawLineStat.eGreyLineDrow;
						debCnt ^= debCnt;
					}
					else
					{
						debCnt++;
					}
				}
				else
				{
					stat = EDrawLineStat.eGreyLineDrow;
				}
				break;
			case EDrawLineStat.eGreyLineDrow:
				if (flag && lastCaCrVal)
				{
					stat = EDrawLineStat.eDrawTmpGreyLine;
				}
				break;
			}
			PosOfCaCrDispfLiveView.Add(stat);
			if (visible)
			{
				PointF pt = koo.transformToBild(pointSave.X, locYpos);
				PointF pt2 = koo.transformToBild(pointDraw.X, locYpos);
				pointSave = pointDraw;
				if (stat == EDrawLineStat.eDrawTestOk)
				{
					g.DrawLine(pen, pt, pt2);
				}
				else
				{
					g.DrawLine(pen0, pt, pt2);
				}
			}
		}

		public void addYValToCaCr(PointF pf, ref Graphics g, ref Koordsyst koo, bool visible)
		{
			pointDraw = pf;
			this.g = g;
			this.koo = koo;
			if (!this.visible && visible)
			{
				redrowCaCr();
			}
			this.visible = visible;
			if (pf.Y <= 10f && pf.Y >= -10f)
			{
				lastCaCrVal = true;
			}
			else
			{
				lastCaCrVal = false;
			}
		}
	}
}
